package com.moose.security.handler;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.moose.api.Result;
import com.moose.entity.log.OperateLog;
import com.moose.entity.sys.SysRole;
import com.moose.entity.sys.SysUser;
import com.moose.enums.ExceptionEnum;
import com.moose.security.util.SecurityUtil;
import com.moose.service.log.OperateLogService;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.stream.Collectors;

/**
 * 登出成功处理器
 *
 * @author 唐国翔
 * @since 2018-12-24 16:02
 * <p>
 * 　　　　　　　　┏┓　　　┏┓+ +
 * 　　　　　　　┏┛┻━━━┛┻┓ + +
 * 　　　　　　　┃　　　　　　　┃
 * 　　　　　　　┃　　　━　　　┃ ++ + + +
 * 　　　　　　 ████━████ ┃+
 * 　　　　　　　┃　　　　　　　┃ +
 * 　　　　　　　┃　　　┻　　　┃
 * 　　　　　　　┃　　　　　　　┃ + +
 * 　　　　　　　┗━┓　　　  ┏━┛
 * 　　　　　　　　　┃　　　┃
 * 　　　　　　　　　┃　　　┃ + + + +
 * 　　　　　　　　　┃　　　┃　　　　Code is far away from bug with the animal protecting
 * 　　　　　　　　　┃　　　┃ + 　　　　神兽保佑,代码无bug
 * 　　　　　　　　　┃　　　┃
 * 　　　　　　　　　┃　　　┃　　+
 * 　　　　　　　　　┃　 　　┗━━━┓ + +
 * 　　　　　　　　　┃ 　　　　　　　┣┓
 * 　　　　　　　　　┃ 　　　　　　　┏┛
 * 　　　　　　　　　┗┓┓┏━┳┓┏┛ + + + +
 * 　　　　　　　　　　┃┫┫　┃┫┫
 * 　　　　　　　　　　┗┻┛　┗┻┛+ + + +
 **/
@Component
public class LogoutSuccessWithLogHandler implements LogoutSuccessHandler {

    @Resource
    private ObjectMapper objectMapper;

    @Resource
    private OperateLogService operateLogService;

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        long start = System.currentTimeMillis();
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        //另启一个线程记录日志
        ThreadUtil.execute(() -> {
            //获取用户信息
            SysUser sysUser = (SysUser) authentication.getPrincipal();
            //获取当前登陆用户ip
            String ip = SecurityUtil.getIpAddress(request);
            operateLogService.save(OperateLog.builder()
                    .operator(sysUser.getName())
                    //多角色用","隔开
                    .operateRole(sysUser.getRoles().parallelStream().map(SysRole::getRoleName).collect(Collectors.joining(StrUtil.COMMA)))
                    .operateTime(start)
                    .operatorIp(ip)
                    .operateActive("登出")
                    .build());
        });
        response.getWriter().write(objectMapper.writeValueAsString(Result.success(ExceptionEnum.LOGOUT_SUCCESS)));
    }
}
